import Wfs from "./wfs";
import React from "react";
import { Collapse } from "antd";
import type { API } from "@/types/api";
import type { UploadProps } from "antd";
import { RcFile } from "antd/es/upload";
import { useNavigate } from "@umijs/max";
import type { CollapseProps } from "antd";
import type { APP } from "@/pages/hosting/typings";
import { useState, useRef, useEffect } from "react";
import Editor, { loader } from "@monaco-editor/react";
import { Space, message, Upload, Radio, Drawer, Tag } from "antd";
import {
    DrawerForm,
    ProForm,
    ProFormSelect,
    ProFormText,
} from "@ant-design/pro-components";
import {
    postDeployApp,
    postReceiveFile,
} from "@/services/hosting/api";

loader.config({ paths: { vs: "/monaco-editor/vs" } });

interface Props {
    ifShow: boolean;
    setIfShow: (value: boolean) => void;
    refreshAllApps: () => void;
    App: APP;
}

export const Deploy: React.FC<Props> = ({
    ifShow,
    setIfShow,
    refreshAllApps,
    App,
}) => {
    const navigate = useNavigate();
    const [form] = ProForm.useForm();
    const [savePath, setSavePath] = useState("");
    const [timeDir, setTimeDir] = useState("");
    const [savePathError, setSavePathError] = useState(false);
    const [isLoading, setIsLoading] = useState(true);
    const [chooseFileFromServer, setChooseFileFromServer] = useState(false);
    const [nginxConfError, setNginxConfError] = useState("");
    const [code, setCode] = useState("");
    const [chooseFilePath, setChooseFilePath] = useState("");
    const [uploadedFileInfo, setUploadedFileInfo] = useState<{ name: string } | null>(null);
    const uploadRef = useRef<any>(null);
    const [position, setPosition] = useState<"local" | "fromServer" | "origin">(
        "local",
    );
    const [stypes, setStypes] = useState<string[]>([]);
    const [currentApp, setCurrentApp] = useState<APP | null>(null);
    const [isInitialized, setIsInitialized] = useState(false);
    const [stypeValue, setStypeValue] = useState<string>("");
    const fontSize = 14;
    const translateStype = (stype: string): string => {
        const lowerStype = stype.toLowerCase();
        switch (lowerStype) {
            case "java" || "Java":
                return "Java服务";
            case "static" || "Static":
                return "前端静态文件";
            default:
                return stype;
        }
    };
    useEffect(() => {
        if (stypeValue === "Static") {
            setCode(App.nginx_conf);
            form.setFieldsValue({
                nginx_conf: App.nginx_conf,
            });
        }
    }, [stypeValue]);

    // 处理传入的App数据
    useEffect(() => {
        if (App && ifShow) {
            let newApp: APP | null = null;
            if (typeof App === "object" && "app_id" in App) {
                newApp = App as APP;
            } else if (typeof App === "object") {
                const appKeys = Object.keys(App);
                if (appKeys.length > 0) {
                    newApp = (App as Record<string, APP>)[appKeys[0]];
                }
            }

            if (
                newApp &&
                (!currentApp || newApp.app_id !== currentApp.app_id)
            ) {
                setCurrentApp(newApp);
                setStypeValue(newApp.stype);
                setIsInitialized(false);
            }
        }
        setStypes([App.stype]);
    }, [App, ifShow]);

    // 上传配置
    const uploadProps: UploadProps = {
        name: "file",
        action: "/api/apps/hosting/receive_file",
        headers: { authorization: "authorization-text" },
        maxCount: 1,
        beforeUpload: (file: RcFile) => {
            const isAllowed =
                stypeValue === "Java"
                    ? file.type === "application/java-archive" ||
                    file.name.endsWith(".jar")
                    : file.name.endsWith(".zip") || file.name.endsWith(".war");

            if (!isAllowed) {
                message.error(
                    stypeValue === "Java"
                        ? "只能上传[.jar]文件!"
                        : "只能上传[.zip]文件!",
                );
                return false;
            }
            return true;
        },
        onChange(info) {
            const { status } = info.file;
            if (status === "uploading") setSavePathError(false);
            if (status === "done") {
                message.success(`${info.file.name} 上传成功`);
                setUploadedFileInfo({ name: info.file.name });
                form.setFieldsValue({
                    file: info.file.response?.message?.path || info.file.name,
                    time_dir: info.file.response?.message?.time_dir || "",
                });
            } else if (status === "error") {
                message.error(`${info.file.name} 上传失败`);
            }
        },
        onRemove() {
            form.setFieldsValue({ file: undefined, time_dir: undefined });
            setSavePath("");
            setUploadedFileInfo(null);
            return true;
        },
        customRequest: async ({ file, onSuccess, onError }) => {
            const formData = new FormData();
            formData.append("file", file as RcFile);
            try {
                const res = await postReceiveFile(formData, App.node, navigate);
                if (typeof onSuccess === "function") {
                    onSuccess("ok", file as RcFile);
                }
                setSavePath(
                    typeof res.message === "object" && res.message.path
                        ? res.message.path
                        : "",
                );
                setTimeDir(
                    typeof res.message === "object" && res.message.time_dir
                        ? res.message.time_dir
                        : "",
                );
                setSavePathError(false);
            } catch (error) {
                if (typeof onError === "function") {
                    onError(error as Error);
                }
            }
        },
    };

    const clearFieldError = (fieldName: string) => {
        form.setFields([{ name: fieldName, errors: [] }]);
    };

    const handleFieldChange = (fieldName: string, value: any) => {
        if (value && value !== "") clearFieldError(fieldName);
    };

    const handleEditorChange = (value: string | undefined) => {
        if (value !== undefined) {
            form.setFieldsValue({ nginx_conf: value });
            if (value.trim() !== "") {
                setNginxConfError("");
            }
        }
    };

    const uploadFromServer = () => {
        setChooseFileFromServer(true);
        message.info("正在从服务器选择文件...");
    };

    const chooseBasePkg = () => {
        setSavePath("0");
        setTimeDir("0");
    };

    const removeSelectedFile = () => {
        setChooseFilePath("");
        setSavePath("");
        setUploadedFileInfo(null);
    };

    const initStype = async () => {
        if (isInitialized) return;

        setIsLoading(true);
        try {
            form.setFieldsValue({ stype: stypes[0] });
            if (currentApp) {
                const initialValues: any = {
                    alias: currentApp.alias || "",
                    version: currentApp.version || "",
                    notes: currentApp.notes || "",
                };

                if (currentApp.stype === "Java") {
                    initialValues.port = currentApp.port || "";
                    initialValues.inpara = currentApp.inpara || "";
                    initialValues.keepalive = currentApp.keepalive === "1";
                } else if (currentApp.stype === "Static") {
                    initialValues.nginx_conf = currentApp.nginx_conf || "";
                    setCode(currentApp.nginx_conf || "");
                }

                form.setFieldsValue(initialValues);
            }
            setIsInitialized(true);
        } catch (error) {
            console.error("初始化失败:", error);
        } finally {
            setIsLoading(false);
        }
    };

    useEffect(() => {
        if (ifShow && currentApp && !isInitialized) {
            initStype();
        }
    }, [ifShow, currentApp, isInitialized]);

    useEffect(() => {
        if (!ifShow) {
            form.resetFields();
            setIsInitialized(false);
        }
    }, [ifShow]);

    const submitForm = async (
        values: API.PostDeployPararm & { stype: string },
    ): Promise<boolean> => {
        setSavePathError(false);
        setNginxConfError("");
        if (savePath === "") {
            setSavePathError(true);
            message.error("请上传文件");
            return false;
        }
        // Static类型需要校验Nginx配置
        if (stypeValue === "Static") {
            const nginxConf = values.nginx_conf || "";
            if (!nginxConf || nginxConf.trim() === "") {
                setNginxConfError("Nginx配置不能为空");
                message.error("Nginx配置不能为空");
                return false;
            }
        }
        const transformedValues: any = {
            app_id: App.app_id,
            save_path: savePath,
            time_dir: timeDir,
            version: values.version || "",
            notes: values.notes || "",
            node: values.node || "0",
        };
        if (stypeValue === "Java") {
            transformedValues.inpara = values.inpara || "";
            transformedValues.port = values.port || "";
            transformedValues.keepalive = values.keepalive ? "1" : "0";
        } else if (stypeValue === "Static") {
            transformedValues.nginx_conf = values.nginx_conf || "";
        }
        try {
            const res = await postDeployApp(
                transformedValues,
                stypeValue.toLowerCase() as "java" | "static",
                navigate,
            ) as API.PostDeployAppResult;
            if (res.status === "error") {
                if (res.status_code === "VERIFICATION_FAILDED") {
                    const fieldErrors = Object.entries(res.message).map(
                        ([fieldName, errorMsg]) => {
                            if (fieldName === "save_path") {
                                setSavePathError(true);
                            }
                            return { name: fieldName, errors: [errorMsg] };
                        },
                    );
                    form.setFields(fieldErrors);
                }
                message.error(res.message as string);
                return false;
            } else if (res.status === "success") {
                message.info(res.message as string);
                refreshAllApps?.();
                return true;
            }
            message.error("未知错误！");
            return false;
        } catch (err) {
            if (err instanceof Error) {
                message.error(err.message);
            } else {
                message.error(String(err));
            }
            return false;
        }
    };

    const items: CollapseProps["items"] = [
        {
            key: "1",
            label: "基础信息",
            children: (
                <>
                    <ProForm.Group>
                        <ProFormText
                            disabled
                            width="md"
                            name="alias"
                            label="应用名称"
                            placeholder="请输入名称"
                            fieldProps={{
                                onChange: (e) => {
                                    handleFieldChange("alias", e.target.value);
                                    form.setFieldsValue({
                                        alias: e.target.value,
                                    });
                                },
                            }}
                        />
                        <ProFormSelect
                            options={stypes.map((stype) => ({
                                label: translateStype(stype),
                                value: stype,
                            }))}
                            disabled
                            width="md"
                            name="stype"
                            label="应用类型"
                            tooltip="托管应用的类型"
                            fieldProps={{
                                onChange: (value: any) => {
                                    handleFieldChange("stype", value);
                                    setStypeValue(value);
                                },
                            }}
                        />
                        <ProFormText
                            width="md"
                            name="version"
                            label="版本号"
                            placeholder="请输入版本号"
                            fieldProps={{
                                onChange: (e) =>
                                    handleFieldChange(
                                        "version",
                                        e.target.value,
                                    ),
                            }}
                        />
                        <ProFormText
                            width="md"
                            name="notes"
                            label="备注"
                            placeholder="请输入备注"
                            fieldProps={{
                                onChange: (e) =>
                                    handleFieldChange("notes", e.target.value),
                            }}
                        />
                    </ProForm.Group>
                    <Space direction="vertical" style={{ width: "100%" }}>
                        <ProForm.Item
                            label="软件包"
                            required
                            style={{ marginBottom: 0 }}
                            validateStatus={savePathError ? "error" : ""}
                            help={savePathError ? "请上传文件" : null}
                        >
                            <Radio.Group
                                value={position}
                                onChange={(e) => {
                                    // 只更新状态，不执行点击逻辑
                                    setPosition(e.target.value);
                                }}
                            >
                                <Radio.Button
                                    value="local"
                                >
                                    本地上传
                                </Radio.Button>
                                <Radio.Button
                                    value="origin"
                                    onClick={(e) => {
                                        e.stopPropagation(); // 阻止事件冒泡
                                        chooseBasePkg();
                                    }}
                                >
                                    当前版本
                                </Radio.Button>
                                <Radio.Button
                                    value="formserver"
                                    onClick={(e) => {
                                        e.stopPropagation(); // 阻止事件冒泡
                                        uploadFromServer();
                                    }}
                                >
                                    从服务器选择
                                </Radio.Button>
                            </Radio.Group>
                            <div
                                style={{ minHeight: "15px", minWidth: "100%", marginTop: "10px" }}
                            >
                                {position === "local" && (
                                    <Upload.Dragger {...uploadProps} ref={uploadRef}>
                                        <p className="ant-upload-text">点击选择文件或拖拽文件到此处上传</p>
                                        <p className="ant-upload-hint">
                                            支持文件类型：jar、zip
                                        </p>
                                    </Upload.Dragger>
                                )}
                                {chooseFilePath && (
                                    <div style={{ marginTop: '10px' }}>
                                        <Tag 
                                            closable 
                                            onClose={removeSelectedFile}
                                            style={{ fontSize: '14px', padding: '5px 10px' }}
                                        >
                                            已选择: {chooseFilePath}
                                        </Tag>
                                    </div>
                                )}
                            </div>
                        </ProForm.Item>

                        {/* Static类型显示Nginx配置编辑器 */}
                        {stypeValue === "Static" && (
                            <ProForm.Item
                                label="Nginx配置"
                                required
                                tooltip="Nginx配置文件内容"
                                style={{ marginBottom: 0 }}
                                validateStatus={nginxConfError ? "error" : ""}
                                help={nginxConfError}
                            >
                                <div
                                    style={{
                                        border: "1px solid #d9d9d9",
                                        borderRadius: "6px",
                                        overflow: "hidden",
                                        position: "relative",
                                    }}
                                >
                                    <Editor
                                        height={"43vh"}
                                        language="nginx"
                                        theme="light"
                                        onChange={handleEditorChange}
                                        value={code}
                                        options={{
                                            fontSize: fontSize,
                                            minimap: { enabled: false },
                                            scrollBeyondLastLine: false,
                                            lineNumbers: "on",
                                            folding: true,
                                            lineDecorationsWidth: 10,
                                            lineNumbersMinChars: 3,
                                            wordWrap: "on",
                                            automaticLayout: true,
                                        }}
                                    />
                                </div>
                                <ProFormText name="nginx_conf" hidden />
                            </ProForm.Item>
                        )}
                    </Space>
                </>
            ),
        },
        // 只在Java类型时显示其他信息
        stypeValue === "Java" && {
            key: "2",
            label: "其他信息",
            children: (
                <>
                    <ProFormText
                        width="xl"
                        name="inpara"
                        label="JVM参数"
                        placeholder="请输入内容"
                        tooltip="应用启动时的JVM传参"
                        fieldProps={{
                            onChange: (e) =>
                                handleFieldChange("inpara", e.target.value),
                        }}
                    />
                    {/* <ProFormSwitch
                        name="keepalive"
                        label="进程保活"
                        tooltip="渔翁将运用后台进程守护技术，保障应用进程的稳定运行"
                        fieldProps={{
                            onChange: (checked) =>
                                handleFieldChange("keepalive", checked),
                        }}
                    /> */}
                </>
            ),
        },
    ].filter(Boolean) as CollapseProps["items"];

    return (
        <>
            <DrawerForm
                form={form}
                onOpenChange={setIfShow}
                title="发布新版本"
                open={ifShow}
                onFinish={submitForm}
                drawerProps={{
                    width: 800,
                    styles: {
                        body: {
                            overflowY: "auto",
                        },
                    },
                }}
            >
                {isLoading ? (
                    <div>加载中...</div>
                ) : (
                    <Collapse items={items} defaultActiveKey={["1"]} />
                )}
            </DrawerForm>

            <Drawer
                title="从服务器选择文件"
                open={chooseFileFromServer}
                width="30%"
                onClose={() => setChooseFileFromServer(false)}
            >
                <Wfs
                    ifshow={chooseFileFromServer}
                    changeShow={setChooseFileFromServer}
                    choosePath={(path: string) => {
                        setChooseFilePath(path);
                        return path;
                    }}
                />
            </Drawer>
        </>
    );
};
